package com.yanqu.road.server.manager.unionwar;

import com.yanqu.road.entity.activity.ActivityConditionInfo;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.unionwar.UnionQunyingTimeInfo;
import com.yanqu.road.entity.activity.unionwar.enums.eTimeInfoPeriodType;
import com.yanqu.road.entity.activity.unionwar.result.CurrentTimeInfo;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroup;
import com.yanqu.road.logic.bussiness.activity.UnionWarActivityBusiness;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.logic.helper.ActivityHelper;
import com.yanqu.road.server.CrossBaseServer;
import com.yanqu.road.server.TempCrossMgr;
import com.yanqu.road.server.manager.union.activitygroup.Cross2UnionActivityGroupMgr;
import com.yanqu.road.server.manger.TempCommonMgr;
import com.yanqu.road.utils.date.DateHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class CrossUnionWarActivityMgr extends TempCrossMgr {

    private static Logger logger = LogManager.getLogger(CrossUnionWarActivityMgr.class.getName());

    private static Map<Integer, ActivityInfo> activityMap;

    private static Map<Integer, List<ActivityConditionInfo>> activityConditionMap;

    //activityId赛制配置
    private static Map<Integer, List<UnionQunyingTimeInfo>> timeInfoMap;
    private static Object loadLockObj = new Object();

    @Override
    public boolean reloadData() {
        synchronized (loadLockObj) {
            loadActivity();
        }
        return true;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

    public static void loadActivity(){
        String nowTimeStr = DateHelper.getCurrentDateTimeString();
        List<Integer> activityTypeList = new ArrayList<>();
        activityTypeList.add(eActivityType.CrossUnionWarActivity.getValue());
        Map<Integer, ActivityInfo> activityInfoMap = ActivityBussiness.getOpenCrossRankActivityInfoMap(activityTypeList, nowTimeStr);
        long serverId = CrossBaseServer.getInstance().getServerId();

        Set<Integer> removeList = new HashSet<>();
        for (ActivityInfo activityInfo : activityInfoMap.values()) {
            if(activityInfo.getCrossId() == serverId){
                continue;
            }
            Map<Integer, UnionActivityGroup> groupMap  = Cross2UnionActivityGroupMgr.getGroupMap(activityInfo.getActivityId());
            boolean inGroup = false;
            if(groupMap != null){
                for (Map.Entry<Integer, UnionActivityGroup> groupEntry : groupMap.entrySet()) {
                    UnionActivityGroup group = groupEntry.getValue();
                    if(group.getCrossServerId() == serverId){
                        inGroup = true;
                        break;
                    }
                }
            }
            if(inGroup){
                continue;
            }
            removeList.add(activityInfo.getActivityId());
        }

        for (int aid : removeList) {
            activityInfoMap.remove(aid);
        }

        List<Integer> activityIdList = new ArrayList<>(activityInfoMap.keySet());
        Map<Integer, List<ActivityConditionInfo>> activityConditionInfoMap = ActivityBussiness.getOpenCrossRankActivityConditionInfoMap(activityIdList);
        Map<Integer, List<UnionQunyingTimeInfo>> tempTimeInfoMap = UnionWarActivityBusiness.getUnionQunyingTimeInfoMap(activityIdList);
        activityMap = activityInfoMap;
        activityConditionMap = activityConditionInfoMap;
        timeInfoMap = tempTimeInfoMap;
    }

    public static void reloadConfig(int activityId) {
        ActivityInfo tmpActivityInfo = ActivityBussiness.getActivityInfoByActivityId(activityId);
        if(tmpActivityInfo != null){
            synchronized (loadLockObj) {
                List<Integer> activityIdList = new ArrayList<>();
                activityIdList.add(activityId);
                Map<Integer, List<ActivityConditionInfo>> activityConditionInfoMap = ActivityBussiness.getOpenCrossRankActivityConditionInfoMap(activityIdList);
                Map<Integer, List<UnionQunyingTimeInfo>> tempTimeInfoMap = UnionWarActivityBusiness.getUnionQunyingTimeInfoMap(activityIdList);
                activityMap.put(activityId, tmpActivityInfo);
                activityConditionMap.put(activityId, activityConditionInfoMap.get(activityId));
                timeInfoMap.put(activityId, tempTimeInfoMap.get(activityId));
            }
        }
    }

    /**
     * 获取所有活动
     * @return
     */
    private static Map<Integer, ActivityInfo> getActivityMap() {
        return new ConcurrentHashMap<>(activityMap);
    }

    public static UnionQunyingTimeInfo getUnionQunyingTimeInfo(int activity, int phase, int session){
        List<UnionQunyingTimeInfo> sessionList = timeInfoMap.get(activity);
        if(sessionList == null){
            return null;
        }
        for(UnionQunyingTimeInfo timeInfo : sessionList){
            if(timeInfo.getType() == phase && timeInfo.getSession() == session){
                return timeInfo;
            }
        }
        return null;
    }

    public static Map<Integer, List<ActivityConditionInfo>> getActivityConditionMap() {
        return new ConcurrentHashMap<>(activityConditionMap);
    }

    public static List<ActivityConditionInfo> getActivityConditionInfoList(int activityId){
        List<ActivityConditionInfo> activityConditionInfoList = activityConditionMap.get(activityId);
        if(null != activityConditionInfoList){
            return new ArrayList<>(activityConditionInfoList);
        }
        return new ArrayList<>();
    }

    public static List<ActivityConditionInfo> getActivityConditionInfoList(int activityId, int conditionType) {
        List<ActivityConditionInfo> activityConditionInfoList = new ArrayList<>();
        List<ActivityConditionInfo> tempActivityConditionInfoList = activityConditionMap.get(activityId);
        for (ActivityConditionInfo activityConditionInfo : tempActivityConditionInfoList) {
            if (activityConditionInfo.getType() == conditionType) {
                activityConditionInfoList.add(activityConditionInfo);
            }
        }
        return activityConditionInfoList;
    }

    public static ActivityConditionInfo getActivityConditionInfo(int activityId, int conditionId){
        List<ActivityConditionInfo> activityConditionInfoList = getActivityConditionInfoList(activityId);
        for(ActivityConditionInfo activityConditionInfo : activityConditionInfoList){
            if(activityConditionInfo.getConditionId() == conditionId){
                return activityConditionInfo;
            }
        }
        return null;
    }

    /**
     * 获取开放的活动集合
     * @return
     */
    public static Map<Integer, ActivityInfo> getOpenActivityMap(){
        Map<Integer, ActivityInfo> dataMap = new ConcurrentHashMap<>();
        for(ActivityInfo activityInfo : getActivityMap().values()){
            if(ActivityHelper.activityInShowTime(activityInfo)){
                dataMap.put(activityInfo.getActivityId(), activityInfo);
            }
        }
        return dataMap;
    }

    /**
     * 获取开放的活动
     * @param activityId
     * @return
     */
    public static ActivityInfo getOpenActivity(int activityId){
        ActivityInfo activityInfo = activityMap.get(activityId);
        if(null == activityInfo){
            synchronized (loadLockObj) {
                activityInfo = activityMap.get(activityId);
                if(null == activityInfo) {
                    loadActivity();
                    TempCommonMgr.reloadCommonData();
                }
            }
            activityInfo = activityMap.get(activityId);
        }
        if(ActivityHelper.activityInShowTime(activityInfo)){
            return activityInfo;
        }
        return null;
    }


    /**
     * 是否积分赛匹配时间
     * @param activityId
     * @return
     */
    public static boolean isScoreMatchUnionTime(int activityId) {
        //积分赛匹配：活动开始后，备战期前1小时，至开战前
        ActivityInfo activityInfo = activityMap.get(activityId);
        if(activityInfo == null){
            return false;
        }
        CurrentTimeInfo currentTimeInfo = getCurrentTimeInfo(activityId);
        UnionQunyingTimeInfo timeInfo = currentTimeInfo.getTimeInfo();
        long gapSecond = System.currentTimeMillis() / 1000 - activityInfo.getBeginTime();
        UnionQunyingTimeInfo zeroTimeInfo = getUnionQunyingTimeInfo(activityId, 1, 0);
        if (gapSecond >= (-60 * 60 + zeroTimeInfo.getBeginTime() * 60) && (timeInfo == null || (timeInfo.getType() == 1 && timeInfo.getSession() == 0))
            && currentTimeInfo.getPeriodType() != eTimeInfoPeriodType.ReceiveTime) {
            return true;
        }
        return false;
    }

    /**
     * 是否匹配商会对手时间
     * @param activityId
     * @return
     */
    public static boolean isMatchUnionTime(int activityId, int stateNo, int session){
        CurrentTimeInfo currentTimeInfo = getCurrentTimeInfo(activityId);
        UnionQunyingTimeInfo timeInfo = currentTimeInfo.getTimeInfo();
        //当前战斗期，不开始匹配下一场次
        if(timeInfo != null && 2 == stateNo && session > timeInfo.getSession() &&
                currentTimeInfo.getPeriodType() == eTimeInfoPeriodType.FightingTime){
            return false;
        }
        //积分赛如果有未匹配的，在开战后，开始补偿单场未匹配的
        if(stateNo == 1){
            if(timeInfo != null && timeInfo.getSession() > 0) {
                return true;
            }
        }
        //决赛匹配:
        if(timeInfo != null && stateNo == 2 && timeInfo.getType() == 2 && (0 == timeInfo.getSession() || session <= timeInfo.getSession())){
            return true;

        }
        //领奖期
        if(currentTimeInfo.getPeriodType() == eTimeInfoPeriodType.ReceiveTime){
            return true;
        }
        return false;
    }

    /**
     * 是否开战时间
     * @param activityId
     * @return
     */
    public static boolean isUnionWarBattleTime(int activityId, int phase, int session){
        CurrentTimeInfo currentTimeInfo = getCurrentTimeInfo(activityId);
        UnionQunyingTimeInfo timeInfo = currentTimeInfo.getTimeInfo();
        if(timeInfo != null){
            if(phase > timeInfo.getType()){
                return false;
            }
            if(phase == timeInfo.getType() && session > timeInfo.getSession()){
                return false;
            }
            //当前session是否在战斗期
            if(phase == timeInfo.getType() && session == timeInfo.getSession() && currentTimeInfo.getPeriodType() != eTimeInfoPeriodType.FightingTime){
                return false;
            }
            if(currentTimeInfo.getPeriodType() == eTimeInfoPeriodType.FightingTime && phase == timeInfo.getType() && session == timeInfo.getSession()){
                ActivityInfo activityInfo = activityMap.get(activityId);
                if(activityInfo == null){
                    return false;
                }
                //周期开始45秒后，开打
                if(currentTimeInfo.isAfterBeginTimeNSecond(activityInfo, 45)){
                    return true;
                }
                return false;
            }
            //补偿其他过期场次
            return true;
        }
        //领奖期补偿
        if(currentTimeInfo.getPeriodType() == eTimeInfoPeriodType.ReceiveTime){
            return true;
        }
        return false;
    }

    /**
     * 获取商会战周期时间
     * @param activityId
     * @return
     */
    public static List<UnionQunyingTimeInfo> getUnionQunyingTimeInfoList(int activityId){
        if(timeInfoMap.containsKey(activityId)){
            return new ArrayList<>(timeInfoMap.get(activityId));
        }
        return new ArrayList<>();
    }

    /**
     * 获取总战斗场次
     * @param activityId
     * @param phase 当前阶段
     * @return
     */
    public static int getAllSession(int activityId, int phase){
        List<UnionQunyingTimeInfo> timeInfoList = getUnionQunyingTimeInfoList(activityId);
        int count = 0;
        for(UnionQunyingTimeInfo timeInfo : timeInfoList){
            if(timeInfo.getType() == phase && timeInfo.getSession() != 0){
                count++;
            }
        }
        return count;
    }

    /**
     * 获取当前活动周期
     * @return
     */
    public static CurrentTimeInfo getCurrentTimeInfo(int activityId){
        CurrentTimeInfo currentTimeInfo = new CurrentTimeInfo();
        ActivityInfo activityInfo = activityMap.get(activityId);
        if(activityInfo == null){
            return currentTimeInfo;
        }
        int currentSecond = DateHelper.getCurrentSecond();
        if(currentSecond >= activityInfo.getBeginShowTime() && currentSecond <= activityInfo.getBeginTime()){
            currentTimeInfo.setPeriodType(eTimeInfoPeriodType.ShowTime);
            return currentTimeInfo;
        }
        //不在活动期间，没有任何阶段、周期
        if(currentSecond >= activityInfo.getEndShowTime() || currentSecond < activityInfo.getBeginShowTime()){
            return currentTimeInfo;
        }
        if(currentSecond >= activityInfo.getEndTime() && currentSecond < activityInfo.getEndShowTime()){
            currentTimeInfo.setPeriodType(eTimeInfoPeriodType.ReceiveTime);
            return currentTimeInfo;
        }
        UnionQunyingTimeInfo current = null;
        if (null != activityInfo) {
            long gapSecond = System.currentTimeMillis() / 1000 - activityInfo.getBeginTime();
            List<UnionQunyingTimeInfo> timeInfoList = timeInfoMap.get(activityId);
            for (int i = 0; i < timeInfoList.size(); i++) {
                UnionQunyingTimeInfo timeInfo = timeInfoList.get(i);
                //beginTime至第一周期之前
                if(timeInfo.getType() == 1 && timeInfo.getSession() == 0 && gapSecond < timeInfo.getBeginTime() * 60){
                    currentTimeInfo.setPeriodType(eTimeInfoPeriodType.ShowTime);
                    return currentTimeInfo;
                }
                if (gapSecond >= timeInfo.getBeginTime() * 60 && gapSecond <= (timeInfo.getBeginTime() + timeInfo.getDurTime()) * 60) {
                    current = timeInfo;
                    if (current.getSession() == 0) {
                        currentTimeInfo.setPeriodType(eTimeInfoPeriodType.PrepareTime);
                    } else {
                        currentTimeInfo.setPeriodType(eTimeInfoPeriodType.FightingTime);
                    }
                } else {
                    if (i < timeInfoList.size() - 1) {
                        UnionQunyingTimeInfo nextTimeInfo = timeInfoList.get(i + 1);
                        if (gapSecond > (timeInfo.getBeginTime() + timeInfo.getDurTime()) * 60 && gapSecond < nextTimeInfo.getBeginTime() * 60) {
                            current = nextTimeInfo;
                            currentTimeInfo.setPeriodType(eTimeInfoPeriodType.PrepareTime);
                        }
                    }
                }
                if (current != null) {
                    break;
                }
            }
        }
        //配置错误,活动结束时间应等于最后一个周期的结束时间(beginTime + durTime)
        if(current == null && currentSecond < activityInfo.getEndTime() && currentSecond > activityInfo.getBeginTime()){
            //logger.error("activity {} endTime not config equals last timeId endTime", activityId);
            currentTimeInfo.setPeriodType(eTimeInfoPeriodType.ReceiveTime);
        }
        currentTimeInfo.setTimeInfo(current);
        return currentTimeInfo;
    }

    @Override
    public boolean removeExpireData() throws Exception {
        logger.info("union war removeExpireData start");
        List<Integer> acList = new ArrayList<>();
        long nowTime = System.currentTimeMillis();
        for (Map.Entry<Integer, ActivityInfo> infoEntry : activityMap.entrySet()) {
            ActivityInfo activityInfo = infoEntry.getValue();
            if((nowTime > activityInfo.getEndShowTime()  * 1000 + 3 * 24 * 3600 * 1000)){
                acList.add(activityInfo.getActivityId());
            }
        }
        for(Integer activityId : acList){
            CrossUnionWarMgr.getUnionWarDetailMap().remove(activityId);
            CrossUnionWarMgr.getUnionWarSimpleMap().remove(activityId);
            CrossUnionWarMgr.getUnionWarStateMap().remove(activityId);
            timeInfoMap.remove(activityId);
            activityConditionMap.remove(activityId);
            activityMap.remove(activityId);
            logger.info("union war removeExpireData {}", activityId);
        }
        return true;
    }
}
